#ifndef THINK_THINK_CONSOLE_INPUT_DEFINITION_H
#define THINK_THINK_CONSOLE_INPUT_DEFINITION_H

static char* think_console_input_definition =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: yunwuxin <448901948@qq.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think\\console\\input;\n"
	"\n"
	"class Definition\n"
	"{\n"
	"\n"
	"    /**\n"
	"     * @var Argument[]\n"
	"     */\n"
	"    private $arguments;\n"
	"\n"
	"    private $requiredCount;\n"
	"    private $hasAnArrayArgument = false;\n"
	"    private $hasOptional;\n"
	"\n"
	"    /**\n"
	"     * @var Option[]\n"
	"     */\n"
	"    private $options;\n"
	"    private $shortcuts;\n"
	"\n"
	"    /**\n"
	"     * 构造方法\n"
	"     * @param array $definition\n"
	"     * @api\n"
	"     */\n"
	"    public function __construct(array $definition = [])\n"
	"    {\n"
	"        $this->setDefinition($definition);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置指令的定义\n"
	"     * @param array $definition 定义的数组\n"
	"     */\n"
	"    public function setDefinition(array $definition)\n"
	"    {\n"
	"        $arguments = [];\n"
	"        $options   = [];\n"
	"        foreach ($definition as $item) {\n"
	"            if ($item instanceof Option) {\n"
	"                $options[] = $item;\n"
	"            } else {\n"
	"                $arguments[] = $item;\n"
	"            }\n"
	"        }\n"
	"\n"
	"        $this->setArguments($arguments);\n"
	"        $this->setOptions($options);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置参数\n"
	"     * @param Argument[] $arguments 参数数组\n"
	"     */\n"
	"    public function setArguments($arguments = [])\n"
	"    {\n"
	"        $this->arguments          = [];\n"
	"        $this->requiredCount      = 0;\n"
	"        $this->hasOptional        = false;\n"
	"        $this->hasAnArrayArgument = false;\n"
	"        $this->addArguments($arguments);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加参数\n"
	"     * @param Argument[] $arguments 参数数组\n"
	"     * @api\n"
	"     */\n"
	"    public function addArguments($arguments = [])\n"
	"    {\n"
	"        if (null !== $arguments) {\n"
	"            foreach ($arguments as $argument) {\n"
	"                $this->addArgument($argument);\n"
	"            }\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加一个参数\n"
	"     * @param Argument $argument 参数\n"
	"     * @throws \\LogicException\n"
	"     */\n"
	"    public function addArgument(Argument $argument)\n"
	"    {\n"
	"        if (isset($this->arguments[$argument->getName()])) {\n"
	"            throw new \\LogicException(sprintf(\'An argument with name \"%s\" already exists.\', $argument->getName()));\n"
	"        }\n"
	"\n"
	"        if ($this->hasAnArrayArgument) {\n"
	"            throw new \\LogicException(\'Cannot add an argument after an array argument.\');\n"
	"        }\n"
	"\n"
	"        if ($argument->isRequired() && $this->hasOptional) {\n"
	"            throw new \\LogicException(\'Cannot add a required argument after an optional one.\');\n"
	"        }\n"
	"\n"
	"        if ($argument->isArray()) {\n"
	"            $this->hasAnArrayArgument = true;\n"
	"        }\n"
	"\n"
	"        if ($argument->isRequired()) {\n"
	"            ++$this->requiredCount;\n"
	"        } else {\n"
	"            $this->hasOptional = true;\n"
	"        }\n"
	"\n"
	"        $this->arguments[$argument->getName()] = $argument;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据名称或者位置获取参数\n"
	"     * @param string|int $name 参数名或者位置\n"
	"     * @return Argument 参数\n"
	"     * @throws \\InvalidArgumentException\n"
	"     */\n"
	"    public function getArgument($name)\n"
	"    {\n"
	"        if (!$this->hasArgument($name)) {\n"
	"            throw new \\InvalidArgumentException(sprintf(\'The \"%s\" argument does not exist.\', $name));\n"
	"        }\n"
	"\n"
	"        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;\n"
	"\n"
	"        return $arguments[$name];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据名称或位置检查是否具有某个参数\n"
	"     * @param string|int $name 参数名或者位置\n"
	"     * @return bool\n"
	"     * @api\n"
	"     */\n"
	"    public function hasArgument($name)\n"
	"    {\n"
	"        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;\n"
	"\n"
	"        return isset($arguments[$name]);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取所有的参数\n"
	"     * @return Argument[] 参数数组\n"
	"     */\n"
	"    public function getArguments()\n"
	"    {\n"
	"        return $this->arguments;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取参数数量\n"
	"     * @return int\n"
	"     */\n"
	"    public function getArgumentCount()\n"
	"    {\n"
	"        return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取必填的参数的数量\n"
	"     * @return int\n"
	"     */\n"
	"    public function getArgumentRequiredCount()\n"
	"    {\n"
	"        return $this->requiredCount;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取参数默认值\n"
	"     * @return array\n"
	"     */\n"
	"    public function getArgumentDefaults()\n"
	"    {\n"
	"        $values = [];\n"
	"        foreach ($this->arguments as $argument) {\n"
	"            $values[$argument->getName()] = $argument->getDefault();\n"
	"        }\n"
	"\n"
	"        return $values;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置选项\n"
	"     * @param Option[] $options 选项数组\n"
	"     */\n"
	"    public function setOptions($options = [])\n"
	"    {\n"
	"        $this->options   = [];\n"
	"        $this->shortcuts = [];\n"
	"        $this->addOptions($options);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加选项\n"
	"     * @param Option[] $options 选项数组\n"
	"     * @api\n"
	"     */\n"
	"    public function addOptions($options = [])\n"
	"    {\n"
	"        foreach ($options as $option) {\n"
	"            $this->addOption($option);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加一个选项\n"
	"     * @param Option $option 选项\n"
	"     * @throws \\LogicException\n"
	"     * @api\n"
	"     */\n"
	"    public function addOption(Option $option)\n"
	"    {\n"
	"        if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {\n"
	"            throw new \\LogicException(sprintf(\'An option named \"%s\" already exists.\', $option->getName()));\n"
	"        }\n"
	"\n"
	"        if ($option->getShortcut()) {\n"
	"            foreach (explode(\'|\', $option->getShortcut()) as $shortcut) {\n"
	"                if (isset($this->shortcuts[$shortcut])\n"
	"                    && !$option->equals($this->options[$this->shortcuts[$shortcut]])\n"
	"                ) {\n"
	"                    throw new \\LogicException(sprintf(\'An option with shortcut \"%s\" already exists.\', $shortcut));\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        $this->options[$option->getName()] = $option;\n"
	"        if ($option->getShortcut()) {\n"
	"            foreach (explode(\'|\', $option->getShortcut()) as $shortcut) {\n"
	"                $this->shortcuts[$shortcut] = $option->getName();\n"
	"            }\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据名称获取选项\n"
	"     * @param string $name 选项名\n"
	"     * @return Option\n"
	"     * @throws \\InvalidArgumentException\n"
	"     * @api\n"
	"     */\n"
	"    public function getOption($name)\n"
	"    {\n"
	"        if (!$this->hasOption($name)) {\n"
	"            throw new \\InvalidArgumentException(sprintf(\'The \"--%s\" option does not exist.\', $name));\n"
	"        }\n"
	"\n"
	"        return $this->options[$name];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据名称检查是否有这个选项\n"
	"     * @param string $name 选项名\n"
	"     * @return bool\n"
	"     * @api\n"
	"     */\n"
	"    public function hasOption($name)\n"
	"    {\n"
	"        return isset($this->options[$name]);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取所有选项\n"
	"     * @return Option[]\n"
	"     * @api\n"
	"     */\n"
	"    public function getOptions()\n"
	"    {\n"
	"        return $this->options;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据名称检查某个选项是否有短名称\n"
	"     * @param string $name 短名称\n"
	"     * @return bool\n"
	"     */\n"
	"    public function hasShortcut($name)\n"
	"    {\n"
	"        return isset($this->shortcuts[$name]);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据短名称获取选项\n"
	"     * @param string $shortcut 短名称\n"
	"     * @return Option\n"
	"     */\n"
	"    public function getOptionForShortcut($shortcut)\n"
	"    {\n"
	"        return $this->getOption($this->shortcutToName($shortcut));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取所有选项的默认值\n"
	"     * @return array\n"
	"     */\n"
	"    public function getOptionDefaults()\n"
	"    {\n"
	"        $values = [];\n"
	"        foreach ($this->options as $option) {\n"
	"            $values[$option->getName()] = $option->getDefault();\n"
	"        }\n"
	"\n"
	"        return $values;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据短名称获取选项名\n"
	"     * @param string $shortcut 短名称\n"
	"     * @return string\n"
	"     * @throws \\InvalidArgumentException\n"
	"     */\n"
	"    private function shortcutToName($shortcut)\n"
	"    {\n"
	"        if (!isset($this->shortcuts[$shortcut])) {\n"
	"            throw new \\InvalidArgumentException(sprintf(\'The \"-%s\" option does not exist.\', $shortcut));\n"
	"        }\n"
	"\n"
	"        return $this->shortcuts[$shortcut];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取该指令的介绍\n"
	"     * @param bool $short 是否简洁介绍\n"
	"     * @return string\n"
	"     */\n"
	"    public function getSynopsis($short = false)\n"
	"    {\n"
	"        $elements = [];\n"
	"\n"
	"        if ($short && $this->getOptions()) {\n"
	"            $elements[] = \'[options]\';\n"
	"        } elseif (!$short) {\n"
	"            foreach ($this->getOptions() as $option) {\n"
	"                $value = \'\';\n"
	"                if ($option->acceptValue()) {\n"
	"                    $value = sprintf(\' %s%s%s\', $option->isValueOptional() ? \'[\' : \'\', strtoupper($option->getName()), $option->isValueOptional() ? \']\' : \'\');\n"
	"                }\n"
	"\n"
	"                $shortcut   = $option->getShortcut() ? sprintf(\'-%s|\', $option->getShortcut()) : \'\';\n"
	"                $elements[] = sprintf(\'[%s--%s%s]\', $shortcut, $option->getName(), $value);\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (count($elements) && $this->getArguments()) {\n"
	"            $elements[] = \'[--]\';\n"
	"        }\n"
	"\n"
	"        foreach ($this->getArguments() as $argument) {\n"
	"            $element = \'<\' . $argument->getName() . \'>\';\n"
	"            if (!$argument->isRequired()) {\n"
	"                $element = \'[\' . $element . \']\';\n"
	"            } elseif ($argument->isArray()) {\n"
	"                $element .= \' (\' . $element . \')\';\n"
	"            }\n"
	"\n"
	"            if ($argument->isArray()) {\n"
	"                $element .= \'...\';\n"
	"            }\n"
	"\n"
	"            $elements[] = $element;\n"
	"        }\n"
	"\n"
	"        return implode(\' \', $elements);\n"
	"    }\n"
	"}\n"
	"\n"
;
#endif